import ProductInfoAPI from '@/api/ProductInfo';
import {
  Box,
  ClickModal,
  FieldCols,
  Icon,
  mapField,
  useCall,
  useEffectRef,
  useReq,
  useTableActions,
  useTableColumns,
  useFormValue,
} from '@/components';
import { forkHandler, groupBy } from '@/utils';
import { Button, Form, message, Table } from 'antd';
import moment from 'moment';
import React, { createContext, useContext, useEffect, useMemo, useState, useCallback } from 'react';

const Context = createContext({ enabledIdList: [], titleMapId: new Map() });

function EditThemeDialog(props) {
  const { item, onOk, onToggle, ...others } = props;
  const [form] = Form.useForm();
  const ctx = useContext(Context);
  const ctxRef = useEffectRef(ctx);

  const handleToggle = useCall(
    forkHandler(onToggle, (visi) => {
      if (visi && item) {
        form.setFieldsValue(item);
      } else {
        form.resetFields();
      }
    }),
  );

  const handleOk = useCall(async () => {
    const formData = await form.validateFields();
    const {
      isShow,
      showContentTitle,
      attachmentUrl,
      richTextInfo,
      tail: { attachmentUrl: tailUrl },
    } = formData;
    const { tail = null, ...head } = item ?? {};

    if (isShow === '1' && ctx.enabledIdList.length >= 10 && (!item?.id || !ctx.enabledIdList.includes(item.id))) {
      const error = '最大允许添加10个启用主题';
      message.warn(error);
      throw error;
    }

    const data = [
      {
        id: head?.id ?? null,
        createTime: head?.createTime ?? moment().format('YYYY-MM-DD'),
        relationCode: '0',
        contentType: '2',
        showContentType: 'PDF_HEAD',
        showContentTitle,
        isShow,
        attachmentUrl,
        richTextInfo,
      },
      {
        id: tail?.id ?? null,
        createTime: tail?.createTime ?? moment().format('YYYY-MM-DD'),
        relationCode: '0',
        contentType: '2',
        showContentType: 'PDF_TAIL',
        showContentTitle,
        isShow,
        attachmentUrl: tailUrl,
        richTextInfo,
      },
    ];

    return onOk?.(data);
  });

  const fields = useMemo(() => {
    const validateTitle = async (r, value) => {
      const titleId = ctxRef.current?.titleMapId.get(value);
      if (titleId && item?.id !== titleId) throw '不可使用重复的主题名称';
    };
    const uploadDisabled = (e, index, form) => {
      const value = useFormValue(form, 'isShow');
      const isDisabled = useCallback(() => {
        // 1是 0否
        if (props.title !== '新增主题模板') {
          if (value == '1') {
            return true;
          } else if (value == '0') {
            return false;
          } else {
            return false;
          }
        } else {
          return false;
        }
      }, [value]);
      return { disabled: isDisabled() };
    };

    return [
      [
        'export',
        '导出格式',
        'checkbox-group',
        {
          required: true,
          initialValue: 'pdf',
          options: [{ label: 'pdf', value: 'pdf' }],
        },
      ],
      [
        'showContentTitle',
        '主题名称',
        null,
        { required: true, maxLength: 10, rules: [{ validator: validateTitle, message: '不可使用重复的主题名称' }] },
      ],
      [
        'isShow',
        '是否启用',
        'radio-group',
        {
          initialValue: '1',
          options: [
            { value: '1', label: '是' },
            { value: '0', label: '否' },
          ],
          extra: '启用状态下不能修改图片',
        },
      ],
      [
        'richTextInfo',
        '缩略图',
        'upload',
        {
          rules: [{ required: true, message: '请上传缩略图' }],
          accept: 'image/*',
          listType: 'picture-card',
          getFieldProps: uploadDisabled,
        },
      ],
      [
        'attachmentUrl',
        '封皮',
        'upload',
        {
          rules: [{ required: true, message: '请上传封皮' }],
          accept: 'image/*',
          listType: 'picture-card',
          getFieldProps: uploadDisabled,
        },
      ],
      [
        ['tail', 'attachmentUrl'],
        '封底',
        'upload',
        {
          rules: [{ required: true, message: '请上传封底' }],
          accept: 'image/*',
          listType: 'picture-card',
          getFieldProps: uploadDisabled,
        },
      ],
    ].map(mapField);
  }, []);

  const content = (
    <Form form={form} component={false}>
      <FieldCols form={form} fields={fields} colProps={{ xs: 18, md: 18, xl: 18 }} rowProps={{ justify: 'center' }} />
    </Form>
  );

  return <ClickModal title='编辑主题模板' {...others} onToggle={handleToggle} onOk={handleOk} content={content} />;
}

function ThemePage(props) {
  const xhr = useReq(() =>
    ProductInfoAPI.view({
      relationCode: '0',
      showContentType: 'PDF_HEAD,PDF_TAIL',
    }),
  );
  const updateXhr = useReq(ProductInfoAPI.insertOrUpdate);
  const [list, setList] = useState([]);

  const ctx = useMemo(() => {
    const enabledIdList = list.reduce((ret, item) => (item.isShow === '1' ? [...ret, item.id] : ret), []);
    const titleMapId = new Map(list.map((i) => [i.showContentTitle, i.id]));
    return { enabledIdList, titleMapId };
  }, [list]);

  const reload = () => {
    xhr.start();
  };

  useEffect(reload, []);

  useEffect(() => {
    if (xhr.result?.data.length) {
      const { PDF_HEAD, PDF_TAIL } = groupBy(xhr.result.data, 'showContentType');
      const tailTitleMap = groupBy(PDF_TAIL, 'showContentTitle');
      PDF_HEAD.forEach((item) => {
        item.tail = tailTitleMap[item.showContentTitle][0] ?? null;
      });
      setList(PDF_HEAD);
    } else {
      setList([]);
    }
  }, [xhr.result]);

  const onToggleIsShow = useCall((row) => {
    let { tail, ...head } = row;
    if (head.isShow === '0' && ctx.enabledIdList.length >= 10) {
      return message.warn('前端最大允许展示10个主题');
    }

    const isShow = head.isShow === '0' ? '1' : '0';
    tail = { ...tail, isShow };
    head = { ...head, isShow };

    updateXhr.start([tail, head]).then(reload);
  });

  const insertData = useCall(forkHandler((data) => ProductInfoAPI.insertOrUpdate(data), reload, true));
  const onRowUpdate = useCall(forkHandler((r, i, data) => ProductInfoAPI.insertOrUpdate(data), reload, true));

  const deleteRow = useCall(forkHandler((row) => ProductInfoAPI.deleteItems([row, row.tail]), reload, true));

  const actionCols = useTableActions(
    {
      edit: {
        dialog: EditThemeDialog,
        itemProp: 'item',
        onOk: onRowUpdate,
        text: (
          <Button size='small' type='link'>
            <Icon type='edit' />
          </Button>
        ),
      },
      toggleIsShow: (r) => (
        <Button size='small' type='link'>
          {r.isShow === '0' ? '启用' : '禁用'}
        </Button>
      ),
      del: {
        confirm: '是否确认删除？',
        onOk: deleteRow,
        text: (
          <Button size='small' type='link'>
            <Icon type='delete' />
          </Button>
        ),
      },
    },
    { onToggleIsShow },
    { width: 100 },
  );

  const columns = useTableColumns([
    { key: 'order', format: 'order', width: 64, title: '序号' },
    { dataIndex: 'showContentTitle', title: '主题名称' },
    { dataIndex: 'createTime', title: '创建时间', format: 'date' },
    { dataIndex: 'isShow', title: '状态', map: ['停用', '已启用'] },
    ...actionCols,
  ]);

  return (
    <Context.Provider value={ctx}>
      <Box flex jus='between'>
        <div />
        <EditThemeDialog title='新增主题模板' onOk={insertData}>
          <Button>+新增主题</Button>
        </EditThemeDialog>
      </Box>

      <Box py={1} />

      <Table
        rowKey='id'
        pagination={false}
        dataSource={list}
        loading={[updateXhr.status, xhr.status].includes('loading')}
        columns={columns}
      />
    </Context.Provider>
  );
}

export default ThemePage;
